﻿using System;
using System.IO;
using System.ServiceProcess;
using PSE.ProcessManager.ConfigurationManager;
using PSE.ProcessManager.Entity;
using PSE.ProcessManager.ServiceManager;

namespace PSE.Deployment.Util
{
    public class ProcessManager
    {
        private static readonly ProcessManager Instance = new ProcessManager();

        //private string _processManagerPath;
        private ConfigurationManager _configurationManager;
        private ServiceManager _serviceManager;

        private ProcessManager()
        {
            if (!PSE.Deployment.Util.WindowsRegistry.HasInstalledInformation(@"PSEComponents-v3\Modules\GP\Server"))
                throw new Exception("O Servidor dos Componentes da plataforma de serviços versão 3 não estão instalados!");

            //_processManagerPath = Path.Combine(PSE.Deployment.Util.WindowsRegistry.GetInstalledInformation("PSEComponents-v3").InstallLocation, @"PSEComponents\ProcessManager");

            _serviceManager = new ServiceManager(new Uri(System.Configuration.ConfigurationManager.AppSettings["InteligenceManagerAddress"]));
            _configurationManager = new ConfigurationManager();
        }

        public static ProcessManager GetInstance()
        {
            return Instance;
        }

        public void AddProduct(string productName)
        {
            if (_configurationManager.ListProducts().Find(p => p.ToUpper() == productName.ToUpper()) == null)
            {
                _configurationManager.AddProduct(productName);
            }
        }

        public bool AddInstance(string productName, string instanceName, string instanceAddress, string processPath, string stsAuthorityCertificateName, string serviceCertificateName)
        {
            return _configurationManager.AddInstance(productName, instanceName, instanceAddress, processPath, stsAuthorityCertificateName, serviceCertificateName);
        }

        public bool AddProcess(string productName,
                               string instanceName,
                               int processId,
                               int inteligenceModuleId,
                               string processName,
                               string description,
                               string instanceContext,
                               string className,
                               string assembly,
                               string failureRecovery,
                               string initializationType)
        {
            ProcessEntity process = new ProcessEntity()
            {
                Id = processId,
                InteligenceModuleId = inteligenceModuleId,
                Name = processName,
                Description = description,
                Class = className,
                Assembly = assembly
            };

            process.InstanceContext = process.ResolveInstanceContext(instanceContext);
            process.FailureRecovery = process.ResolveFailureAction(failureRecovery);
            process.InitializationType = process.ResolveStartUpType(initializationType);

            return _configurationManager.AddProcess(productName, instanceName, process);
        }

        public bool RemoveInstance(string productName, string instanceName)
        {
            return _configurationManager.RemoveInstance(productName, instanceName);
        }

        public bool RemoveProduct(string productName)
        {
            return _configurationManager.RemoveProduct(productName);
        }

        public bool Start()
        {
            return _serviceManager.Start();
        }

        public bool Stop()
        {
            return _serviceManager.Stop();
        }

        public ServiceControllerStatus GetStatus()
        {
            return _serviceManager.GetStatus();
        }

        public bool StartInstance(string productKey, string instanceKey)
        {
            return _serviceManager.StartInstance(productKey, instanceKey);
        }

        public bool StopInstance(string productKey, string instanceKey)
        {
            return _serviceManager.StopInstance(productKey, instanceKey);
        }
    }
}